using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using bitzhuwei.Compiler;

namespace bitzhuwei.AnsiCFormat {
    /// <summary>
    /// Correspond to the Vn node unary_expression in the grammar(AnsiC).
    /// </summary>
    internal partial class Vnunary_expression : IFullFormatter {
        // [014]=unary_expression : postfix_expression ;
        // [015]=unary_expression : '++' unary_expression ;
        // [016]=unary_expression : '--' unary_expression ;
        // [017]=unary_expression : unary_operator cast_expression ;
        // [018]=unary_expression : 'sizeof' unary_expression ;
        // [019]=unary_expression : 'sizeof' '(' type_name ')' ;

        private readonly TokenRange _scope;
        public TokenRange Scope => _scope;

        public void Format(TextWriter writer, FormatContext context) {
            throw new NotImplementedException();
        }

        public void FullFormat(BlankConfig preConfig, TextWriter writer, FormatContext context) {
            throw new NotImplementedException();
        }

        public IEnumerable<string> YieldTokens(TextWriter writer, FormatContext context) {
            throw new NotImplementedException();
        }
        public readonly Item last;
        public readonly List<Token> list = new();
        /// <summary>
        /// [014]=unary_expression : postfix_expression ;
        /// </summary>
        /// <param name="last0"></param>
        public Vnunary_expression(Vnpostfix_expression last0) {
            this.last = new postfix_(last0);
        }
        /// <summary>
        /// [017]=unary_expression : unary_operator cast_expression ;
        /// </summary>
        /// <param name="last1"></param>
        /// <param name="last0"></param>
        public Vnunary_expression(Vnunary_operator last1, Vncast_expression last0) {
            this.last = new cast_(last1, last0);
        }
        /// <summary>
        /// [019]=unary_expression : 'sizeof' '(' type_name ')' ;
        /// </summary>
        /// <param name="last3"></param>
        /// <param name="last2"></param>
        /// <param name="last1"></param>
        /// <param name="last0"></param>
        public Vnunary_expression(Token last3, Token last2, Vntype_name last1, Token last0) {
            this.last = new siezof_(last3, last2, last1, last0);
        }

        public abstract class Item { }
        public class postfix_ : Item {
            // [014]=unary_expression : postfix_expression ;
            private readonly Vnpostfix_expression last0;

            public postfix_(Vnpostfix_expression last0) {
                this.last0 = last0;
            }
        }
        public class cast_ : Item {
            // [017]=unary_expression : unary_operator cast_expression ;
            private readonly Vnunary_operator last1;
            private readonly Vncast_expression last0;

            public cast_(Vnunary_operator last1, Vncast_expression last0) {
                this.last1 = last1;
                this.last0 = last0;
            }
        }
        public class siezof_ : Item {
            private readonly Token last3;
            private readonly Token last2;
            private readonly Vntype_name last1;
            private readonly Token last0;

            // [019]=unary_expression : 'sizeof' '(' type_name ')' ;

            public siezof_(Token last3, Token last2, Vntype_name last1, Token last0) {
                this.last3 = last3;
                this.last2 = last2;
                this.last1 = last1;
                this.last0 = last0;
            }
        }

        /// <summary>
        /// [015]=unary_expression : '++' unary_expression ;
        /// [016]=unary_expression : '--' unary_expression ;
        /// [018]=unary_expression : 'sizeof' unary_expression ;
        /// </summary>
        /// <param name="r1"></param>
        internal void Insert(
            Token r1/* reserved word is omissible */
        ) {
            this.list.Insert(0, r1);
        }
    }
}
